/*
 * 精读编辑
 */
import * as React from 'react';
import { connect } from 'react-redux';
import { get } from 'lodash';

import ContentEditable from 'components/common/ContentEditable';

import LoadableComponent from 'components/common/LoadableComponent';
const LoadableSentenceEdit = LoadableComponent(() => import('components/common/EditSentence'));
const LoadableImageEdit = LoadableComponent(() => import('./EditImage'));
const LoadableImageAnswerEdit = LoadableComponent(() => import('./EditImageAnswer'));
const LoadableDialogBox = LoadableComponent(() => import('components/common/DialogBox'));

import { fetchPageDetail, createPage, savePage } from 'actions/page';

import { Modal, Tooltip, Spin, Icon, Button, message, Avatar } from 'antd';
import './Edit.scss';

interface EditProps {
  dispatch: (action: any) => any;
  newPrecisionCallback: (id: number) => any;
  lessonId: number;
  precisionId: any;
}
interface EditState {
  editQuestion: any;
  editTextAnswer: any;
  editImageAnswer: any;
  editPrecision: any;
  editSentenceIndex: number;
}

class EditPrecision extends React.Component<EditProps, EditState> {
  static defaultProps: EditProps = {
    dispatch: () => {},
    newPrecisionCallback: () => {},
    precisionId: 0,
    lessonId: 0,
  };

  constructor(props: EditProps) {
    super(props);
    this.state = {
      editQuestion: null,
      editTextAnswer: null,
      editImageAnswer: null,
      editPrecision: null,
      editSentenceIndex: -1,
    };
  }

  componentDidMount() {
    if (this.props.precisionId) {
      this.handleFetchPrecisionDetail();
    }
  }

  componentWillReceiveProps(nextProps: any) {
    const { precisionId } = nextProps;
    const { precisionId: oldPrecisionId } = this.props;

    if (precisionId !== oldPrecisionId) {
      if (precisionId) {
        this.handleFetchPrecisionDetail(precisionId);
      } else {
        this.setState({
          editPrecision: null,
        });
      }
    }
  }

  handleFetchPrecisionDetail = (precisionId: number = this.props.precisionId) => {
    const { dispatch, lessonId } = this.props;

    dispatch(fetchPageDetail(lessonId, precisionId)).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        this.setState({
          editPrecision: result.response.data,
        });
      }
    });
  };

  closeQuestionEditor = () => {
    this.setState({
      editQuestion: null,
    });
  };
  openQuestionEditor = (editQuestion: any = 0, editSentenceIndex: number = -1) => {
    this.setState({
      editQuestion,
      editSentenceIndex,
    });
  };

  closeTextAnswerEditor = () => {
    this.setState({
      editTextAnswer: null,
    });
  };
  openTextAnswerEditor = (editTextAnswer: any = 0, editSentenceIndex: number = -1) => {
    this.setState({
      editTextAnswer,
      editSentenceIndex,
    });
  };
  closeImageAnswerEditor = () => {
    this.setState({
      editImageAnswer: null,
    });
  };
  openImageAnswerEditor = (editImageAnswer: any = 0, editSentenceIndex: number = -1) => {
    this.setState({
      editImageAnswer,
      editSentenceIndex,
    });
  };

  handleSavePrecision = (data: Record<string, any>, callback = () => {}) => {
    const { dispatch, lessonId, precisionId, newPrecisionCallback } = this.props;

    const action = precisionId
      ? savePage(lessonId, precisionId, data)
      : createPage(lessonId, 2, data);

    dispatch(action).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        message.success('保存成功');
        if (!precisionId) {
          newPrecisionCallback(result.response.data);
        } else {
          this.handleFetchPrecisionDetail();
        }
        callback();
      }
    });
  };

  // 图片答案
  handleSaveImage = (data: Record<string, any>) => {
    const { editPrecision, editSentenceIndex } = this.state;
    let sentences = get(editPrecision, 'content.sentences', []);

    const { relatedImageId, answerImage: image, answerAudio: audio } = data;
    const type = 'answer';

    let item: any = {
      relatedImageId,
      image,
      audio,
      type,
    };

    if (editSentenceIndex === -1) {
      // new sentence
      sentences.push(item);
    } else {
      // edit sentence
      sentences[editSentenceIndex] = item;
    }
    let content = { ...editPrecision.content, sentences };

    this.handleSavePrecision({ content }, () => {
      this.closeImageAnswerEditor();
    });
  };

  // 文本问题|答案
  handleSaveSentence(type: string, data: Record<string, any>) {
    const { editPrecision, editSentenceIndex, editQuestion } = this.state;
    let content = get(editPrecision, 'content', null);
    let sentences = get(content, 'sentences', []);

    const { audio, sentence, words } = data;

    let item: any = {
      sentence,
      words,
      type,
    };
    if (audio) {
      item = { ...item, audio };
    }
    if (type === 'answer') {
      const { relatedImageId } = data;
      item = { ...item, relatedImageId };
    }

    if (editSentenceIndex === -1) {
      // new sentence
      sentences.push(item);
    } else {
      // edit sentence
      sentences[editSentenceIndex] = item;
    }
    content = { ...content, sentences };

    this.handleSavePrecision({ content }, () => {
      if (editQuestion !== null) {
        this.closeQuestionEditor();
      } else {
        this.closeTextAnswerEditor();
      }
    });
  }

  // 名字不需要组装到content里面
  handleSaveName = (name: string) => {
    const { precisionId, newPrecisionCallback } = this.props;
    let data: any = { name };
    const content = get(this.state.editPrecision, 'content', null);
    if (content) {
      data = { ...data, content };
    }

    this.handleSavePrecision(data, () => {
      if (precisionId) {
        newPrecisionCallback(precisionId);
      }
    });
  };

  renderToolbar() {
    const { editPrecision } = this.state;

    return (
      <div className="test-parser-name text-left">
        <h4 className="test-parser-name-text">
          <ContentEditable tip="编辑名称" onChange={this.handleSaveName}>
            {get(editPrecision, 'name', '')}
          </ContentEditable>
        </h4>
        <hr style={{ color: '#DCE8F1' }} />
      </div>
    );
  }

  // 保存提交交互图片数组
  handleImageCallback = (images: any[]) => {
    let content = get(this.state.editPrecision, 'content', null);
    content = { ...content, images };
    this.handleSavePrecision({ content });
  };

  // 如果删除的是问题，则关联的答案一并删除
  handleRemoveSentence(type: string, sentenceIndex: number) {
    let content = get(this.state.editPrecision, 'content', null);
    const { sentences, ...other } = content;
    const deleteNum = type === 'question' ? 2 : 1;
    sentences.splice(sentenceIndex, deleteNum);
    content = { sentences, ...other };

    this.handleSavePrecision({ content });
  }

  // 如果删除的是问题，则关联的答案一并删除
  confirmToDelete(item: any, index: number) {
    let content = '你确定要删除此句子吗？';
    if (item.type === 'question') {
      content += '关联的答案也将一并删除！';
    }
    Modal.confirm({
      title: '危险，慎重操作',
      content,
      okText: '确定',
      cancelText: '取消',
      iconType: 'info-circle',
      onOk: () => {
        this.handleRemoveSentence(item.type, index);
      },
    });
  }

  handleEditSentence = (item: any, index: number) => {
    if (item.type === 'question') {
      this.openQuestionEditor(item, index);
    } else {
      const sentence = get(item, 'sentence', '');
      if (sentence) {
        this.openTextAnswerEditor(item, index);
      } else {
        this.openImageAnswerEditor(item, index);
      }
    }
  };

  renderTextOrImage(item: any) {
    const sentence = get(item, 'sentence', '');
    const image = get(item, 'image', null);

    let descHtml = null;
    if (sentence) {
      // 多行的换行显示
      const desc = item.sentence.replace(/\n/g, '<br />');
      descHtml = <div dangerouslySetInnerHTML={{ __html: desc }} />;
    } else {
      descHtml = <img src={image.uri} style={{ width: 100 }} />;
    }

    return descHtml;
  }

  renderQuestion(item: any, index: number) {
    return (
      <div
        key={index}
        style={{ textAlign: 'left', display: 'flex', float: 'left' }}
        className="clear-both">
        <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />{' '}
        <LoadableDialogBox
          message={this.renderTextOrImage(item)}
          onRemove={() => {
            this.confirmToDelete(item, index);
          }}
          onEdit={() => {
            this.handleEditSentence(item, index);
          }}
        />
      </div>
    );
  }

  renderAnswer(item: any, index: number) {
    return (
      <div
        key={index}
        style={{ textAlign: 'right', display: 'flex', float: 'right' }}
        className="clear-both">
        <LoadableDialogBox
          message={this.renderTextOrImage(item)}
          boxPos="right"
          onRemove={() => {
            this.confirmToDelete(item, index);
          }}
          onEdit={() => {
            this.handleEditSentence(item, index);
          }}
        />
        <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
      </div>
    );
  }

  renderSentenceList() {
    const sentences = get(this.state.editPrecision, 'content.sentences', []);

    if (sentences.length === 0) {
      return (
        <p className="loading-placeholder">
          <Icon type="frown-o" />
          &nbsp;还没有数据
        </p>
      );
    }

    return (
      <div>
        {sentences.map((item: any, index: number) => {
          return item.type === 'question'
            ? this.renderQuestion(item, index)
            : this.renderAnswer(item, index);
        })}
      </div>
    );
  }

  renderSentence() {
    const content = get(this.state.editPrecision, 'content', null);
    const images = get(content, 'images', []);
    let { editQuestion, editImageAnswer, editTextAnswer } = this.state;

    return (
      <div>
        <h4
          className="text-left test-parser-sub-title"
          style={{ float: 'left', display: 'flex', alignItems: 'center' }}>
          问题&nbsp;&nbsp;
          <Tooltip key="add sentence" title="添加问题">
            <Button
              disabled={images.length === 0}
              shape="circle"
              type="primary"
              icon="plus"
              onClick={() => {
                this.openQuestionEditor();
              }}
            />
          </Tooltip>
        </h4>
        {images.length > 0 && (
          <h4
            className="text-left test-parser-sub-title"
            style={{ float: 'right', display: 'flex', alignItems: 'center' }}>
            答案&nbsp;&nbsp;
            <Tooltip title="图片">
              <Button
                type="primary"
                icon="picture"
                onClick={() => {
                  this.openImageAnswerEditor();
                }}
              />
            </Tooltip>
            &nbsp;
            <Tooltip title="文本">
              <Button
                type="primary"
                icon="book"
                onClick={() => {
                  this.openTextAnswerEditor();
                }}
              />
            </Tooltip>
          </h4>
        )}
        <div className="clear-both" />
        {this.renderSentenceList()}

        {editQuestion !== null && (
          <LoadableSentenceEdit
            editSentence={editQuestion}
            onCancel={this.closeQuestionEditor}
            onOk={this.handleSaveSentence.bind(this, 'question')}
          />
        )}
        {editImageAnswer !== null && (
          <LoadableImageAnswerEdit
            editSentence={editImageAnswer}
            relateImages={images}
            onCancel={this.closeImageAnswerEditor}
            onOk={this.handleSaveImage}
          />
        )}
        {editTextAnswer !== null && (
          <LoadableSentenceEdit
            editSentence={editTextAnswer}
            relateImages={images}
            needRelateImages={true}
            onCancel={this.closeTextAnswerEditor}
            onOk={this.handleSaveSentence.bind(this, 'answer')}
          />
        )}
      </div>
    );
  }

  render() {
    const { editPrecision } = this.state;

    const id = get(editPrecision, 'id', 0);
    const images = get(editPrecision, 'content.images', []);
    return (
      <div className="test-parser-option-item text-left">
        <Spin spinning={false}>
          <div className="text-center">
            {this.renderToolbar()}
            <LoadableImageEdit
              precisionId={id}
              images={images}
              onCallback={this.handleImageCallback}
            />
            {this.renderSentence()}
          </div>
        </Spin>
      </div>
    );
  }
}

interface OwnProps {
  lessonId: number;
  precisionId: number;
  newPrecisionCallback: (id: number) => any;
}

function mapStateToProps(state: any, ownProps: OwnProps) {
  let { lessonId, precisionId, newPrecisionCallback } = ownProps;

  return {
    lessonId,
    precisionId,
    newPrecisionCallback,
  };
}

export default connect(mapStateToProps)(EditPrecision);
